<template>
  <RemindDialog
    v-if="dialogVisible"
    v-model="dialogVisible"
    :duration="10000"
    @close="onDialogClose"
  >
    <template #default>
      <div class="remind-dialog-content">
        <div v-if="dialogReminds.length === 1">
          <div class="remind-row remind-single">
            <span class="remind-index">1.</span>
            <span class="remind-time">{{ formatTime(dialogReminds[0].time) }}</span>
            <span class="remind-desc">{{ dialogReminds[0].description }}</span>
          </div>
        </div>
        <div v-else>
          <ul class="remind-list">
            <li v-for="(item, idx) in dialogReminds" :key="item.id" class="remind-row remind-single">
              <span class="remind-index">{{ idx + 1 }}.</span>
              <span class="remind-time">{{ formatTime(item.time) }}</span>
              <span class="remind-desc">{{ item.description }}</span>
            </li>
          </ul>
        </div>
      </div>
    </template>
  </RemindDialog>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
import RemindDialog from './RemindDialog.vue';
import config from '@/config.js';
import { useUserStore } from '@/store/modules/user.js';

// 构造 WebSocket 地址
const WS_URL = (config.wsBaseUrl || '').replace(/^http/, 'ws') + '/websocket/remind';

// Pinia 用户信息
const userStore = useUserStore();
const userIdRef = computed(() => userStore.id || localStorage.getItem('userId') || '0');

// 弹窗 state
const dialogVisible = ref(false);
const dialogReminds = ref([]);

// 防止重复播放
const hasSpokenThisDialog = ref(false);
const lastDialogSpeakAt = ref(0);
const isPlayingTTS = ref(false);

// ws 实例
const ws = ref(null);
let reconnectTimer = null;
const lastUserId = ref(null);

// 已播报提醒的缓存（防止重复播报）
const spokenReminds = new Set();
const SPEAK_TTL = 60 * 1000; // 1分钟内不重复播报
const remindTimers = []; // 用于清理定时器

// 消息去重缓存
const recentMessages = new Set();

// 心跳相关
const HEARTBEAT_INTERVAL = 30000; // 30s 发送一次
const PONG_TIMEOUT = 10000; // 10s 未收到 pong 视为超时
let heartbeatTimer = null;
let pongTimer = null;

// 全局变量跟踪用户交互状态
let userHasInteracted = false;

// 检查是否有用户交互权限
function hasUserInteractionPermission() {
  return userHasInteracted;
}

// 激活音频上下文，解决自动播放被阻止的问题
function activateAudioContext() {
  try {
    // 激活Web Audio API上下文
    if (window.AudioContext || window.webkitAudioContext) {
      const AudioContext = window.AudioContext || window.webkitAudioContext;
      const audioContext = new AudioContext();
      if (audioContext.state === 'suspended') {
        audioContext.resume().then(() => {
          console.log('[Remind] Web Audio API已激活');
        }).catch(error => {
          console.warn('[Remind] Web Audio API激活失败:', error);
        });
      }
    }
  } catch (error) {
    console.warn('[Remind] 音频激活失败:', error);
  }
}

// 设置页面级别的用户交互监听器
function setupUserInteractionListener() {
  const handleUserInteraction = () => {
    if (!userHasInteracted) {
      userHasInteracted = true;
      console.log('[Remind] 检测到用户交互，激活音频权限');
      
      // 激活音频上下文
      activateAudioContext();
    }
  };
  
  // 监听用户交互事件
  document.addEventListener('click', handleUserInteraction, { once: true });
  document.addEventListener('touchstart', handleUserInteraction, { once: true });
  document.addEventListener('keydown', handleUserInteraction, { once: true });
  
  console.log('[Remind] 用户交互监听器已设置，等待用户交互');
}

function connectWebSocket() {
  // 避免重复连接
  if (ws.value && ws.value.readyState === WebSocket.OPEN) return;
  
  try { 
    ws.value = new WebSocket(WS_URL); 
  } catch(e) { 
    console.error('WS 创建失败', e); 
    scheduleReconnect();
    return; 
  }
  
  const bindUserId = userIdRef.value;
  ws.value.onopen = () => {
    console.log('Remind WS connected for user', bindUserId);
    // 连接成功后发送用户认证信息
    if (bindUserId && bindUserId !== '0') {
      ws.value.send(JSON.stringify({ 
        type: 'auth', 
        userId: bindUserId 
      }));
    }
    startHeartbeat();
  };
  
  ws.value.onclose = () => {
    stopHeartbeat();
    // 若组件还在且用户仍是当前ID，尝试重连
    if (bindUserId === userIdRef.value && validUserId(userIdRef.value)) {
      console.log('Remind WS closed, retry in 3s');
      scheduleReconnect();
    }
  };
  
  ws.value.onerror = (err) => {
    console.error('Remind WS error', err);
    // 添加更详细的错误信息
    if (err.target && err.target.readyState === WebSocket.CLOSED) {
      console.warn('WebSocket连接已关闭，可能原因：');
      console.warn('1. 后端服务未启动');
      console.warn('2. 防火墙阻止连接');
      console.warn('3. nginx代理配置问题');
      console.warn('4. 网络连接问题');
    }
  };
  
  ws.value.onmessage = (evt) => handleMessage(evt.data);
}

function scheduleReconnect() {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
  }
  reconnectTimer = setTimeout(() => {
    if (validUserId(userIdRef.value)) {
      connectWebSocket();
    }
  }, 3000);
}

function closeWebSocket() {
  if (ws.value) {
    try { 
      ws.value.close(); 
    } catch(_) {}
  }
  ws.value = null;
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
}

function handleMessage(raw) {
  let data; 
  try { 
    data = JSON.parse(raw); 
  } catch(e) { 
    console.warn('提醒消息解析失败', e, raw); 
    return; 
  }
  
  // 心跳 pong
  if (data && data.type === 'pong') {
    // 收到 pong 说明连接正常
    if (pongTimer) {
      clearTimeout(pongTimer);
      pongTimer = null;
    }
    return;
  }
  
  // 添加消息去重
  const messageKey = JSON.stringify(data);
  if (recentMessages.has(messageKey)) {
    console.log('[Remind] 检测到重复消息，忽略');
    return;
  }
  recentMessages.add(messageKey);
  
  // 限制缓存大小
  if (recentMessages.size > 100) {
    const firstKey = recentMessages.keys().next().value;
    recentMessages.delete(firstKey);
  }
  
  // 处理不同类型的消息
  if (data.type === 'reminder_alert') {
    // 处理单个提醒消息
    processIncomingList([data]);
  } else if (Array.isArray(data)) {
    // 处理数组格式的消息
    processIncomingList(data);
  } else if (data && Array.isArray(data.list)) {
    // 处理包含list属性的消息
    processIncomingList(data.list);
  } else if (data && data.userId && data.time && data.description) {
    // 处理单个提醒对象
    processIncomingList([data]);
  }
}

// 处理提醒列表
function processIncomingList(list) {
  if (!Array.isArray(list)) return;
  const mine = list.filter(r => String(r.userId) === String(userIdRef.value));
  if (!mine.length) return;
  
  // 立即播报：同一批次合并（保持原顺序）
  const withIds = mine.map(r => ({ ...r, id: buildId(r) }));
  if (withIds.length === 1) {
    showRemind(withIds[0]);
  } else {
    showMergedRemind(withIds);
  }
}

function buildId(r) {
  return `${r.userId || userIdRef.value || 'u'}_${r.time || Date.now()}_${(r.description || '').slice(0, 20)}`;
}

function showRemind(remind) {
  // 检查是否已经播报过
  if (isRemindSpoken(remind)) {
    return;
  }
  
  // 标记为已播报
  markRemindAsSpoken(remind);
  
  // 显示提醒
  const opening = !dialogVisible.value;
  dialogReminds.value = [remind];
  if (opening) {
    dialogVisible.value = true;
    hasSpokenThisDialog.value = false;
  }
  maybeSpeakForDialog();
}

function showMergedRemind(reminds) {
  if (!reminds || !reminds.length) return;
  
  // 过滤已播报的提醒
  const newReminds = reminds.filter(r => !isRemindSpoken(r));
  if (!newReminds.length) return;
  
  // 标记为已播报
  newReminds.forEach(r => markRemindAsSpoken(r));
  
  // 显示提醒
  const opening = !dialogVisible.value;
  dialogReminds.value = newReminds;
  if (opening) {
    dialogVisible.value = true;
    hasSpokenThisDialog.value = false;
  }
  maybeSpeakForDialog();
}

// 检查提醒是否已播报
function isRemindSpoken(remind) {
  const id = remind.id || buildId(remind);
  return spokenReminds.has(id);
}

// 标记提醒为已播报
function markRemindAsSpoken(remind) {
  const id = remind.id || buildId(remind);
  spokenReminds.add(id);
  
  // 设置定时器，一段时间后移除标记
  const timer = setTimeout(() => {
    spokenReminds.delete(id);
    const index = remindTimers.indexOf(timer);
    if (index > -1) {
      remindTimers.splice(index, 1);
    }
  }, SPEAK_TTL);
  
  remindTimers.push(timer);
}

function formatTime(timeStr) {
  if (!timeStr) return '';
  const m = String(timeStr).match(/(\d{1,2}:\d{2})/);
  return m ? m[1] : timeStr;
}

// 启动一次性播报
function maybeSpeakForDialog() {
  if (dialogVisible.value && !hasSpokenThisDialog.value) {
    // 立即设置播放状态
    hasSpokenThisDialog.value = true;
    lastDialogSpeakAt.value = Date.now();
    
    // 播报提醒
    speakReminds();
  }
}

// 播报提醒
function speakReminds() {
  // 重置播放状态，确保可以播放
  isPlayingTTS.value = false;
  
  // 构建播报文本
  let finalText = '';
  if (dialogReminds.value.length === 1) {
    finalText = dialogReminds.value[0].description;
  } else {
    finalText = `您有${dialogReminds.value.length}条提醒：`;
    dialogReminds.value.forEach((remind, index) => {
      finalText += `第${index + 1}条，${remind.description}。`;
    });
  }
  
  // 使用浏览器TTS播报
  playWithBrowserTTS(finalText);
}

// 使用浏览器TTS播报
function playWithBrowserTTS(text) {
  try {
    // 检查浏览器是否支持speechSynthesis
    if (!window.speechSynthesis) {
      console.warn('[Remind] 浏览器不支持speechSynthesis');
      return;
    }
    
    // 停止当前播放
    window.speechSynthesis.cancel();
    
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.rate = 1.0;
    utterance.pitch = 1.0;
    utterance.volume = 1.0;
    utterance.lang = 'zh-CN';
    
    utterance.onstart = () => {
      console.log('[Remind] 浏览器TTS开始播放');
      isPlayingTTS.value = true;
    };
    
    utterance.onend = () => {
      console.log('[Remind] 浏览器TTS播放完成');
      isPlayingTTS.value = false;
    };
    
    utterance.onerror = (event) => {
      console.warn('[Remind] 浏览器TTS播放失败:', event.error);
      isPlayingTTS.value = false;
      
      // 如果是被中断且还有重试次数，则重试
      if (event.error === 'interrupted') {
        console.log('[Remind] TTS被中断，500ms后重试');
        setTimeout(() => {
          playWithBrowserTTS(text);
        }, 500);
      }
    };
    
    // 延迟一点时间再播放，确保页面状态稳定
    setTimeout(() => {
      window.speechSynthesis.speak(utterance);
    }, 100);
    
  } catch (error) {
    console.warn('[Remind] 浏览器TTS播报异常:', error);
    isPlayingTTS.value = false;
  }
}

function onDialogClose() {
  dialogReminds.value = [];
  dialogVisible.value = false;
  hasSpokenThisDialog.value = false;
  // 重置TTS状态
  isPlayingTTS.value = false;
  
  // 停止当前的语音播报
  if (window.speechSynthesis) {
    window.speechSynthesis.cancel();
  }
}

function validUserId(id) { 
  return id && id !== '0'; 
}

// 监听用户ID变化
watch(userIdRef, (newVal, oldVal) => {
  if (!validUserId(newVal)) {
    // 无效ID时，确保彻底断开并清理
    closeWebSocket();
    stopHeartbeat();
    clearRemindState();
    lastUserId.value = null;
    return;
  }
  
  if (newVal === lastUserId.value && ws.value) return; // 无变化
  
  console.log('[Remind] userId changed', oldVal, '=>', newVal);
  clearRemindState();
  closeWebSocket();
  lastUserId.value = newVal;
  connectWebSocket();
}, { immediate: true });

// 清理提醒状态
function clearRemindState() {
  dialogVisible.value = false;
  dialogReminds.value = [];
  hasSpokenThisDialog.value = false;
  // 重置TTS状态
  isPlayingTTS.value = false;
  
  // 清理已播报提醒缓存
  spokenReminds.clear();
  
  // 清理所有定时器
  remindTimers.forEach(timer => clearTimeout(timer));
  remindTimers.length = 0;
}

// 心跳实现
function startHeartbeat() {
  stopHeartbeat();
  heartbeatTimer = setInterval(() => {
    if (!ws.value || ws.value.readyState !== WebSocket.OPEN) return;
    // 发送 ping
    try { 
      ws.value.send(JSON.stringify({ type: 'ping', t: Date.now() })); 
    } catch(e) { 
      /* ignore */ 
    }
    
    // 设定 pong 超时
    if (pongTimer) clearTimeout(pongTimer);
    pongTimer = setTimeout(() => {
      console.warn('心跳超时，准备重连');
      closeWebSocket();
      connectWebSocket();
    }, PONG_TIMEOUT);
  }, HEARTBEAT_INTERVAL);
}

function stopHeartbeat() {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  }
  if (pongTimer) {
    clearTimeout(pongTimer);
    pongTimer = null;
  }
}

onMounted(() => {
  // 初始化由 watch 负责
  setupUserInteractionListener();
  
  // 页面加载时尝试激活音频上下文
  activateAudioContext();
});

onUnmounted(() => { 
  closeWebSocket(); 
  clearRemindState(); 
  stopHeartbeat(); 
});
</script>

<style scoped>
.remind-dialog-content {
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
  max-width: 100%;
  max-height: 50vh;
  overflow-y: auto;
  padding: 12px 16px;
}
.remind-list { 
  list-style: none; 
  padding: 0; 
  margin: 0; 
}
.remind-row { 
  display: flex; 
  align-items: flex-start; 
  gap: 12px; 
  font-size: 20px; 
  line-height: 1.6; 
  margin-bottom: 8px; 
  color: #222; 
}
.remind-single { 
  margin: 8px 0; 
}
.remind-index { 
  flex: 0 0 2em; 
  width: 2em; 
  text-align: right; 
  font-weight: 600; 
  margin-right: 4px; 
}
.remind-time { 
  flex: 0 0 auto; 
  min-width: 5.5em; 
  color: #222; 
  font-weight: 600; 
  margin-right: 8px; 
  white-space: nowrap; 
}
.remind-desc { 
  flex: 1 1 auto; 
  color: #222; 
  font-size: 20px; 
  letter-spacing: 0.5px; 
  white-space: pre-wrap; 
  word-break: break-word; 
  overflow-wrap: anywhere; 
}
</style>